﻿// For an introduction to the Blank template, see the following documentation:
// http://go.microsoft.com/fwlink/?LinkId=232509
(function () {
    "use strict";

    var app = WinJS.Application;
    var appdata = Windows.Storage.ApplicationData.current;
    WinJS.strictProcessing();


    var localFolder = appdata.localFolder;


    var downTimer = new timers.DownTimer();
    var length = 3600;//s, i.e. 60 minutes
    var isDown = false;
    var intervalTimer;
    var _refreshInterval = 100; //every 100ms = 10FPS
    var timeList = new WinJS.Binding.List();

    app.onsettings = function (eventObject) {
        eventObject.detail.applicationcommands = {
            // Add an About command
            "about": {
                href: "/html/about.html",
                title: WinJS.Resources.getString('aboutPageTitle').value
            }
            //,
            //"settings": {
            //    href: "/html/settings.html",
            //    title: WinJS.Resources.getString('settingsPageTitle').value
            //}
        }

        WinJS.UI.SettingsFlyout.populateSettings(eventObject);
    };

    app.onactivated = function (eventObject) {
        if (eventObject.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.launch) {

            Windows.UI.WebUI.WebUIApplication.addEventListener("resuming", resumingHandler, false);

            if (eventObject.detail.previousExecutionState !==
                Windows.ApplicationModel.Activation.ApplicationExecutionState.terminated) {
                // TODO: This application has been newly launched. Initialize 
                // your application here.
                    restoreTimeList();
                
            } else {
                // TODO: This application has been reactivated from suspension. 
                // Restore application state here.
            }

            window.addEventListener("resize", onResize);

            eventObject.setPromise(WinJS.UI.processAll());
            eventObject.setPromise(WinJS.Resources.processAll());

            //we try to always restore...
            var time = appdata.roamingSettings.values["time"];
            var storedLength = appdata.roamingSettings.values["length"];
            if (time) {
                downTimer.time = time;
                downTimer.length = storedLength;
                length = storedLength/1000;
            }
            else {
                if (storedLength) {
                    downTimer.length = storedLength;
                    length = storedLength / 1000;
                }
            }

            var isDownSetting = appdata.roamingSettings.values["isDown"];
            if (isDownSetting) {
                isDown = true;
            }
            else {
                downTimer.length = 0;
            }

            configButtons();
            configRefresh();

            document.getElementById('cmdStartStop').winControl.addEventListener("click", function () {
                if (downTimer.isRunning()) {
                    addLap();
                    stop();
                    configRefresh();
                }
                else {
                    addLap('--:--:--');
                    start();
                    configRefresh();
                }
            }, false);
            document.getElementById('cmdLap').winControl.addEventListener("click", function () {
                if (downTimer.isRunning()) {
                    addLap();
                }
            }, false);

            document.getElementById('cmdClear').winControl.addEventListener("click", function () {
                downTimer.stop();
                var timeListLength = timeList.length;
                for (var i = 0; i < timeListLength; i++) {
                    timeList.pop();
                }
                configButtons();
                storeSettings(); //store new time
                configRefresh();
            }, false);
            document.getElementById('cmdUp').winControl.addEventListener("click", function () {
                stop();
                isDown = false;
                downTimer.changeLength(0, 0, 0);
                storeSettings();
                configButtons();
                refresh();
            }, false);
            document.getElementById('cmdDown').winControl.addEventListener("click", function () {
                stop();
                isDown = true;
                downTimer.changeLength(0, 0, length);
                storeSettings();
                configButtons();
                refresh();
            }, false);

            //make the app bar visible
            var appBar = document.getElementById('appBar');
            appBar.winControl.sticky = true;
            appBar.winControl.show();

        }
    };

    function addLap(line) {
        if (!isDown) {
            if (line) {
                if (timeList.length > 0)
                    timeList.dataSource.insertAtStart(null, line);
            }
            else {
                timeList.dataSource.insertAtStart(null, downTimer.toString());
            }
            storeTimeList();
        }
    }

    function resumingHandler(e) {
        configButtons();
        configRefresh();
    }

    app.oncheckpoint = function (eventObject) {
        // TODO: This application is about to be suspended. Save any state
        // that needs to persist across suspensions here. You might use the
        // WinJS.Application.sessionState object, which is automatically
        // saved and restored across suspension. If you need to complete an
        // asynchronous operation before your application is suspended, call
        // eventObject.setPromise().
        if (intervalTimer) {
            clearInterval(intervalTimer);
            intervalTimer = null;
        }

    };

    function hideButtons() {
        var appBar = document.getElementById('appBar');
        appBar.winControl.hideCommands([cmdUp, cmdDown, cmdClear, cmdSeparator]);
    }
    function showButtons() {
        var appBar = document.getElementById('appBar');
        appBar.winControl.showCommands([cmdUp, cmdDown, cmdClear, cmdSeparator]);
    }
    function onResize() {
        var viewStates = Windows.UI.ViewManagement.ApplicationViewState;
        var myViewState = Windows.UI.ViewManagement.ApplicationView.value;
        switch(myViewState){
            case viewStates.snapped:
                hideButtons();
                break;
            case viewStates.filled:
            case viewStates.fullScreenLandscape:
            case viewStates.fullScreenPortrait:
                showButtons();
                break;
        }
    }

    function start() {
        //start
        if (isDown) {
            if(length>0)
                downTimer.start(length);
        }
        else
            downTimer.start(0);

        storeSettings();
        configButtons();
    }


    function stop() {
        //stop
        downTimer.stop();

        //clear roaming
        storeSettings();
        configButtons();

        refresh();
    }

    function storeSettings() {
        if (downTimer.isRunning()) {
            appdata.roamingSettings.values["time"] = downTimer.time;
            appdata.roamingSettings.values["length"] = downTimer.length; //use downtimer length, in milliseconds
        }
        else {
            appdata.roamingSettings.values["time"] = null;
            appdata.roamingSettings.values["length"] = length*1000; //use default length, it is in seconds, but we store millis
        }
        appdata.roamingSettings.values["isDown"] = isDown;        
        storeTimeList();
    }

    var storing = false;
    function storeTimeList() {
        if (!storing) {
            storing = true;
            if (timeList) {
                localFolder.createFileAsync("dataFile.txt", Windows.Storage.CreationCollisionOption.replaceExisting)
          .then(function (dataFile) {
              var times = timeList.join(',');
              return Windows.Storage.FileIO.writeTextAsync(dataFile, times);
          }).done(function () {
              storing = false;
          });
            }
        }
    }

    function restoreTimeList() {
        if (!storing) {
            storing = true;

            localFolder.getFileAsync("dataFile.txt")
            .then(function (dataFile) {
                return Windows.Storage.FileIO.readTextAsync(dataFile);
            })
            .done(
                    function (values) {
                        if (values) {
                            //timeList = new WinJS.Binding.List();
                            for (var i = 0; i < timeList.length; i++) {
                                timeList.pop();
                            }

                            var valueArray = values.split(',');
                            valueArray.forEach(function (value) {
                                timeList.push(value);
                            });
                        }
                        storing = false;
                    },
                    function (err) {
                        storing = false;
                    });
        }
    }

    function configRefresh() {
        //assign button events
        if (downTimer.isRunning()) {
            if (intervalTimer) {
            }
            else {
                intervalTimer = setInterval(refresh, _refreshInterval);
            }
        }
        else {
            if (intervalTimer) {
                clearInterval(intervalTimer);
                intervalTimer = null;
            }
            //always refresh screen
            refresh();
        }
    }

    function configButtons() {
        // stopwatch or down timer...
        document.getElementById('cmdUp').winControl.selected = !isDown;
        document.getElementById('cmdDown').winControl.selected = isDown;
        document.getElementById('timeList').style.visibility = isDown ? 'hidden' : 'visible';
        if (isDown) {
            appBar.winControl.hideCommands([cmdLap]);
        } else {
            appBar.winControl.showCommands([cmdLap]);
        }

        //start or stop
        if (downTimer.isRunning()) {
            switchEditorVisible(false);

            updateBadge();
            var cmd = document.getElementById('cmdStartStop').winControl;
            cmd.icon = 'stop';
            cmd.label = WinJS.Resources.getString('cmdStop').value;
            cmd.tooltip = WinJS.Resources.getString('cmdStopTooltip').value;
        }
        else {
            Windows.UI.Notifications.BadgeUpdateManager.createBadgeUpdaterForApplication().clear();

            var cmd = document.getElementById('cmdStartStop').winControl;
            cmd.icon = 'play';
            cmd.label = WinJS.Resources.getString('cmdStart').value;
            cmd.tooltip = WinJS.Resources.getString('cmdStartTooltip').value;

            switchEditorVisible(isDown);
        }
    }

    function switchEditorVisible(isVisible) {
        var buttons = document.querySelectorAll(".timer-buttons");

        for (var i = 0; i < buttons.length; i++) {
            if (isVisible) {

                buttons[i].style.visibility = "";
            }
            else {
                buttons[i].style.visibility = "hidden";
            }
        }
    }

    function updateBadge() {
        var Notifications = Windows.UI.Notifications;
        var badgeXml;
        var badgeAttributes;

        // Get an XML DOM version of a specific template by using getTemplateContent.
        badgeXml = Notifications.BadgeUpdateManager.getTemplateContent(Notifications.BadgeTemplateType.badgeGlyph);
        badgeAttributes = badgeXml.getElementsByTagName("badge");
        badgeAttributes[0].setAttribute("value", "playing");

        // Create a badge notification from the XML content.
        var badgeNotification = new Notifications.BadgeNotification(badgeXml);

        // Send the badge notification to the app's tile.
        Notifications.BadgeUpdateManager.createBadgeUpdaterForApplication().update(badgeNotification);
    }

    function refresh() {
        var timeElement = document.getElementById("time");
        var s;
        if (isDown && !downTimer.isRunning()) {
            s = timers.DownTimer.MillisecondsToTimeString(length * 1000);
        }
        else {
            s = downTimer.toString();
        }

        timeElement.setAttribute("aria-valuenow", downTimer.time);
        timeElement.setAttribute("aria-valuetext", s);

        document.getElementById("hoursD").textContent = s[0];
        document.getElementById("hours").textContent = s[1];
        document.getElementById("minutesD").textContent = s[3];
        document.getElementById("minutes").textContent = s[4];
        document.getElementById("secondsD").textContent = s[6];
        document.getElementById("seconds").textContent = s[7];

        if (!downTimer.isRunning() && intervalTimer) {
            configRefresh();
            configButtons();
        }
    }

    app.start();

    function increaseHours() {
        if(downTimer.hours()<59)
            downTimer.changeLength(downTimer.hours() + 1, downTimer.minutes(), 0);
        else
            downTimer.changeLength(59, downTimer.minutes(), 0);
        length = downTimer.length / 1000;
        refresh();
    }

    function decreaseHours() {
        if (downTimer.hours() > 0)
            downTimer.changeLength(downTimer.hours() - 1, downTimer.minutes(), 0);
        else
            downTimer.changeLength(0, downTimer.minutes(), 0);
        length = downTimer.length / 1000;
        refresh();
    }

    function increaseMinutes() {
        if (downTimer.minutes() < 59)
            downTimer.changeLength(downTimer.hours(), downTimer.minutes() + 1, 0);
        else
            downTimer.changeLength(downTimer.hours(), 59, 0);
        length = downTimer.length / 1000;
        refresh();
    }

    function decreaseMinutes() {
        if (downTimer.minutes() >0)
            downTimer.changeLength(downTimer.hours(), downTimer.minutes() - 1, 0);
        else
            downTimer.changeLength(downTimer.hours(), 0, 0);
        length = downTimer.length / 1000;
        refresh();
    }

    var actionTimer;
    var actionTimerCount=0;

    function startActionTimer(action) {
        if (actionTimer)
            clearInterval(actionTimer);
        actionTimerCount = 0;
        var foo;
        switch (action) {
            case actions.increaseHour:
                foo = increaseHours;
                break;
            case actions.decreaseHour:
                foo = decreaseHours;
                break;
            case actions.increaseMin:
                foo = increaseMinutes;
                break;
            case actions.decreaseMin:
                foo = decreaseMinutes;
                break;
        }

        var test = function (x) {
            actionTimerCount++;
            foo();
            refresh();
            if (actionTimerCount == 5) {
                clearInterval(actionTimer);
                actionTimer=setInterval(test, 200, x);
            }
            else if (actionTimerCount == 10) {
                clearInterval(actionTimer);
                actionTimer=setInterval(test, 100, x);
            }
        }
        actionTimer = setInterval(test, 300,action);
    }

    function stopTimer() {
        if (actionTimer) {
            clearInterval(actionTimer);
            actionTimer = null;
        }
    }
    
    //enumeration 1 increaseMin 2 decreaseMin 3 increaseHour 4 decreaseHour
    var actions={"increaseMin":1, "decreaseMin":2, "increaseHour":3, "decreaseHour":4};
    WinJS.Namespace.define("defaultPage", {
        itemList: timeList,
        minutesMouseDown: function (v) {
            if (v > 0) {
                increaseMinutes();
                startActionTimer(actions.increaseMin);
            }
            else {
                decreaseMinutes();
                startActionTimer(actions.decreaseMin);
            }
        },
        hoursMouseDown: function (v) {
            if (v > 0) {
                increaseHours();
                startActionTimer(actions.increaseHour);
            }
            else {
                decreaseHours();
                startActionTimer(actions.decreaseHour);
            }
        },
        mouseUp: function () {
            stopTimer();
        }
    });
})();
